<?php
/**
 * FileController.php
 *
 * @category    Madoqua
 * @package     Module
 * @subpackage  Theme
 */

/** base class */
require_once 'Madoqua/Controller/Action/Abstract.php';

/**
 * Theme_FileController
 *
 * controller for serving (static) files belonging to themes. Certainly
 * not the prettiest solution, but it will have to do for now.
 *
 * @category    Madoqua
 * @package     Module
 * @subpackage  Theme
 */
class Theme_FileController extends Madoqua_Controller_Action_Abstract
{
    /**
     * serve a file
     *
     * @todo add mime headers
     */
    public function serveAction()
    {
        $this->getHelper('viewRenderer')->setNeverRender();
        Zend_Layout::getMvcInstance()->disableLayout();
        //no view rendering/layout
        
        $file = $this->getFile();
        //the file to be served
        
        $fileModified = filemtime($file);
        //time file was last modified

        $expires = (int) $this->_config->theme->fileexpire;
        //expire time for theme assets        
        
        $request = getallheaders();
        foreach($request as $key => $val) {
            $request[strtolower($key)] = $val;
        }
        //capitalization bug
        if (isset($request['if-modified-since'])) {
            $modifiedSince = explode(';', $request['if-modified-since']);
            $modifiedSince = strtotime($modifiedSince[0]);
        } else {
            $modifiedSince = time();
        }
        //requested modified since

        $this->getResponse()->setHeader('Expires', gmdate("D, d M Y H:i:s", (time() + $expires)) . " GMT", true);
        $this->getResponse()->setHeader('Cache-Control', 'max-age=' . $expires . ', must-revalidate', true);
        $this->getResponse()->setHeader('Pragma', '', true);
        //reset ZF headers for cache control to allow for caching          
        
        $this->getResponse()->setRawHeader('Last-Modified: ' . gmdate('D, d M Y H:i:s', $fileModified) . ' GMT');
        //last modified header (so we can revalidate later)
        
        if ($modifiedSince <= $fileModified) {
            //not modified, so exit
            $this->getResponse()->setRawHeader('HTTP/1.1 304 Not Modified');  
            $this->getResponse()->sendHeaders();
            //FUCKITYFUCK
            exit();  
        }
        //check for modification date        

        $this->_modelLoader->load('Theme_File');
        $mimeType = Theme_File::getMimeType($file);
        //figure out the mime type for the file
        
        if ($mimeType !== false) {
            //we have a mime type \ó/
            $this->getResponse()->setRawHeader('Content-Type:' . $mimeType . ';');
        }
        
        $contents = file_get_contents($file);
        //file contents

        $this->getResponse()->setBody($contents);
        //set the file contents as the body        
    }
    
    /**
     * get the requested file
     * 
     * @return string
     */
    private function getFile() 
    {
        $theme = $this->getRequest()->getParam('theme');
        $file = $this->getRequest()->getParam('file');
        //fetch the params

        if (empty($theme) || empty($file)) {
            throw new Exception('Theme and file parameters must be set for this action');
        }

        $directory = realpath(Madoqua_Application::getDataDirectory() . DIRECTORY_SEPARATOR  . 'themes/');
        //themes directory

        $themeDirectory = $directory . '/' . $theme;
        //the theme dir (withing the themes directory)

        if (!file_exists($themeDirectory)) {
            throw new Exception('Theme does not exist: ' . $theme);
        }
        //check whether the theme itself exists
         
        $file = $themeDirectory . '/public/' . $file;
        //the requested file

        if (!file_exists($file)) {
            throw new Exception('File does not exist in theme ' . $theme . ': ' . $file);
        }

        $checkDir = realpath(dirname($file));
        if (count(explode(DIRECTORY_SEPARATOR, $checkDir)) < count(explode(DIRECTORY_SEPARATOR, $directory)) + 1) {
            //check whether requested directory is under a theme's dir
            throw new Exception('Requested file can not live lower than the theme directory.');
        }
        
        return $file;
    }
    
    /**
     * detect whether browser will accept gzip
     *
     * @return bool
     */
    private function canGzip() {
        $acceptedEncoding = str_replace(" ","", strtolower($_SERVER['HTTP_ACCEPT_ENCODING']));
        $acceptedEncoding = explode(",", $acceptedEncoding);
        //what does the browser accept?
        
        return in_array("gzip", $acceptedEncoding);
        //is gzip amongst them?
    }
}